package com.simulation.ctrl;

import cn.hutool.extra.ftp.Ftp;
import com.simulation.service.ExecutorService;
import com.simulation.utils.SSHRemoteCall;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;

/**
 * @author zhangxn
 * @date 2023/1/1  15:14
 */
@Slf4j
@RestController
@RequestMapping("/file")
@CrossOrigin(origins = "*")
public class FileController {

    @Autowired
    private ExecutorService executorService;

    @Value("${file.score.filePath}")
    private String fileScorePath;

    @Value("${file.download.temp.filePath}")
    private String fileDownloadTempePath;

    @Value("${file.upload.main.filePath}")
    private String fileUploadMainPath;

    @Value("${file.compile.filePath}")
    private String fileCompileFilePath;


    /**
     * @param file
     * @param request
     * @return
     */
    @PostMapping("/upload")
    public String uploadFile(@RequestParam("file") MultipartFile file, HttpServletRequest request) {
        String fileName = file.getOriginalFilename();
        File fileLocal = new File(fileName);
        OutputStream out = null;
        try {
            //获取文件流，以文件流的方式输出到新文件
            out = new FileOutputStream(fileLocal);
            byte[] ss = file.getBytes();
            for (int i = 0; i < ss.length; i++) {
                out.write(ss[i]);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (out != null) {
                try {
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        try {
            SSHRemoteCall.getInstance()
                    .sshRemoteCallLogin(SSHRemoteCall.ipAddress, SSHRemoteCall.userName, SSHRemoteCall.password);
            SSHRemoteCall.getInstance()
                    .uploadFile(fileUploadMainPath, fileLocal.getAbsolutePath());
            new Thread(new Runnable() {
                @Override
                public void run() {
                    executorService.execLinuxCommod("sh " + fileCompileFilePath + "/build.sh", "build");
                }
            }).start();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "callback({\"state\":\"success\"})";
    }


    /**
     * @param path     想要下载的文件的路径
     * @param response
     * @功能描述 下载文件:
     */
    @RequestMapping("/download")
    public void download(String path, HttpServletResponse response) throws Exception {
        try {
            path = "/opt/workspace/stm32f103rbt6-fw_led/.pio/build/genericSTM32F103RB/firmware.elf";
            String fileName = path.substring(path.lastIndexOf("/") + 1);
            SSHRemoteCall.getInstance()
                    .sshRemoteCallLogin(SSHRemoteCall.ipAddress, SSHRemoteCall.userName, SSHRemoteCall.password);
            SSHRemoteCall.getInstance()
                    .fileDownload(path, fileDownloadTempePath + fileName );
            // path是指想要下载的文件的路径
            File file = new File(fileDownloadTempePath + fileName);
            log.info(file.getPath());
            // 获取文件名
            String filename = file.getName();
            // 获取文件后缀名
            String ext = filename.substring(filename.lastIndexOf(".") + 1).toLowerCase();
            log.info("文件后缀名：" + ext);

            // 将文件写入输入流
            FileInputStream fileInputStream = new FileInputStream(file);
            InputStream fis = new BufferedInputStream(fileInputStream);
            byte[] buffer = new byte[fis.available()];
            fis.read(buffer);
            fis.close();

            // 清空response
            response.reset();
            // 设置response的Header
            response.setCharacterEncoding("UTF-8");
            //Content-Disposition的作用：告知浏览器以何种方式显示响应返回的文件，用浏览器打开还是以附件的形式下载到本地保存
            //attachment表示以附件方式下载 inline表示在线打开 "Content-Disposition: inline; filename=文件名.mp3"
            // filename表示文件的默认名称，因为网络传输只支持URL编码的相关支付，因此需要将文件名URL编码后进行传输,前端收到后需要反编码才能获取到真正的名称
            response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(filename, "UTF-8"));
            // 告知浏览器文件的大小
            response.addHeader("Content-Length", "" + file.length());
            OutputStream outputStream = new BufferedOutputStream(response.getOutputStream());
            response.setContentType("application/octet-stream");
            outputStream.write(buffer);
            outputStream.flush();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }

    /**
     * @param content
     * @功能描述 保存文件
     */
    @RequestMapping("/writeToFile")
    public String writeToFile(@RequestParam("content") String content) throws Exception {
        File f1 = new File(fileScorePath);
        OutputStream out = null;
        BufferedWriter bw = null;
        if (f1.exists()) {
            out = new FileOutputStream(f1);
            bw = new BufferedWriter(new OutputStreamWriter(out, "utf-8"));
            bw.write(content);
            bw.flush();
            bw.close();
        } else {
            System.out.println("文件不存在");
        }
        return "callback({\"state\":\"success\"})";
    }

}
